package wc.assignmentKeys;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import wc.fileUtil.FileCollector;
import wc.fileUtil.FileReader;
import wc.fileUtil.exception.NoReadableFileException;
import wc.parserUtil.ParserWords;

public class IDF {
	
	private HashMap<String, Integer> _freqInCollection = new HashMap<String, Integer>();
	private int _countFiles;

	public IDF(FileCollector fileCollector, FileReader fileReader, ParserWords parserWords) {
		_countFiles = fileCollector.getFileCount();
		
		for(File f : fileCollector.getFiles()) {
			HashMap<String, Boolean> wordContainList = new HashMap<String, Boolean>();
			try {
				fileReader.parseFile(f);
			} catch (NoReadableFileException e) {
				e.printStackTrace();
			}
			for(String line : fileReader.getFileContent()) {
				parserWords.parseLine(line, true);
				for(String word : parserWords.getItems()) {
					wordContainList.put(word, true);
				}
			}
			for(String key : wordContainList.keySet()) {
				if(_freqInCollection.containsKey(key)) {
					int freq = _freqInCollection.get(key);
					_freqInCollection.put(key, freq + 1);
				}
			}
		}
	}
	
	public HashMap<String, Integer> getFrequency() {
		return _freqInCollection;
	}

	@SuppressWarnings("unchecked")
	public List<Entry<String, Float>> getIDF() {
		Map<String, Float> idfUnsort = new HashMap<String, Float>();
        for(String key : _freqInCollection.keySet()) {
            idfUnsort.put(key, (float) Math.log(_countFiles / _freqInCollection.get(key)));
        }

        List<Map.Entry<String, Float>> idf = new ArrayList<Map.Entry<String, Float>>(idfUnsort.entrySet());
        Collections.sort(idf, new Comparator<Object>() {
            public int compare(Object o, Object o1) {
				Map.Entry<String, Float> e1 = (Map.Entry<String, Float>)o;
                Map.Entry<String, Float> e2 = (Map.Entry<String, Float>)o1;
                Float first = (Float)e1.getValue();
                Float second = (Float)e2.getValue();
                if(first > second) {
                	return -1;
                } else if(first < second) {
                	return 1;
                } else {
                	return -e1.getKey().toLowerCase().compareTo(e2.getKey().toLowerCase());
                }
            }
        });
		return idf;
	}
	
}
